package nccloud.bs.gl.voucher.datasource;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import nc.bs.framework.common.NCLocator;
import nc.bs.gl.voucher.VoucherBO;
import nc.bs.logging.Logger;
import nc.bs.pub.filesystem.IAttachManageConst;
import nc.itf.gl.voucher.IVoucher;
import nc.itf.uap.print.IPrintEntry;
import nc.itf.uap.print.IPrintTemplateQry;
import nc.ui.pub.print.IDataSource;
import nc.ui.pub.print.version55.print.PrintException;
import nc.vo.gl.pubvoucher.DetailVO;
import nc.vo.gl.pubvoucher.VoucherVO;
import nc.vo.ml.NCLangRes4VoTransl;
import nc.vo.pub.BusinessException;
import nc.vo.pub.BusinessRuntimeException;
import nc.vo.pub.print.PrintCellVO;
import nc.vo.pub.print.PrintVO;
import nccloud.pub.gl.print.GLNoPreviewPrintInfo;
import nccloud.pub.gl.print.VoucherPrintDataSource;
import nccloud.pubitf.platform.attachment.IAttachmentService;
import nccloud.pubitf.platform.print.IPrintInfo;
import nccloud.pubitf.uap.print.vo.NoPreviewPrintInfo;
import nccloud.uap.print.service.NoPreviewAbstractPrintService;

public class VoucherNoPreviewPrintService extends NoPreviewAbstractPrintService {
	public IDataSource[] getDataSources(IPrintInfo info) {
		GLNoPreviewPrintInfo printinfo = (GLNoPreviewPrintInfo) info;
		String[] ids = printinfo.getIds();
		Map<String, Object> userMap = printinfo.getUserMap();
		int m_printsubjlevel = 0;
		int m_printasslevel = 0;
		boolean isParallelPrint = false;
		String printTemplateID = printinfo.getPrintTemplateID();
		int printpagelength = 5;
		int totaltype = 0;
		boolean splitfinf = false;
		try {
			PrintVO printVO = NCLocator.getInstance().lookup(IPrintTemplateQry.class).getPrintVO(printTemplateID);
			PrintCellVO[] cellVOs = printVO.getCellVOs();
			if (cellVOs != null) {
				for (PrintCellVO printCellVO : cellVOs) {
					if (printCellVO.getVvar() != null && printCellVO.getVvar().startsWith("voucher90")) {
						isParallelPrint = true;
						break;
					}
				}
			}
			printpagelength = printVO.getTemplateVO().getIbreakposition().intValue();
		} catch (BusinessException e1) {
			Logger.error(e1.getMessage(), e1);
			throw new BusinessRuntimeException(e1.getMessage());
		}
		if (userMap != null) {
			if (userMap.containsKey("printsubjlevel")) {
				if (userMap.get("printsubjlevel") instanceof Integer) {
					m_printsubjlevel = ((Integer) userMap.get("printsubjlevel")).intValue();
				} else {
					String printsubjlevel = (String) ((userMap.get("printsubjlevel") == null) ? "0" : userMap.get("printsubjlevel"));
					m_printsubjlevel = Integer.valueOf(printsubjlevel).intValue();
				}
			}

			if (userMap.containsKey("printasslevel")) {
				if (userMap.get("printasslevel") instanceof Integer) {
					m_printasslevel = ((Integer) userMap.get("printasslevel")).intValue();
				} else {
					String printasslevel = (String) ((userMap.get("printasslevel") == null) ? "0" : userMap.get("printasslevel"));
					m_printasslevel = Integer.valueOf(printasslevel).intValue();
				}
			}

			if (userMap.containsKey("totaltype")) {
				if (userMap.get("totaltype") instanceof Integer) {
					totaltype = ((Integer) userMap.get("totaltype")).intValue();
				} else {
					String totaltypestr = (String) ((userMap.get("totaltype") == null) ? "0" : userMap.get("totaltype"));
					totaltype = Integer.valueOf(totaltypestr).intValue();
				}
			}

			if (userMap.containsKey("splitfinf")) {
				Object spv = ((Map) userMap.get("splitfinf")).get("value");
				if (spv instanceof Boolean) {
					splitfinf = ((Boolean) spv).booleanValue();
				}
			}
		}

		List<IDataSource> dslist = new ArrayList<IDataSource>();
		try {
			if (ids != null && ids.length > 0) {
				Set<String> idset = new HashSet<String>(Arrays.asList(ids.clone()));
				VoucherVO[] vos = NCLocator.getInstance().lookup(IVoucher.class).queryByPks(ids);
				Map<String, VoucherVO> voMap = new HashMap<String, VoucherVO>();
				if (vos != null) {
					for (VoucherVO voucherVO : vos) {
						if (voucherVO != null) {
							idset.remove(voucherVO.getPk_voucher());
							voMap.put(voucherVO.getPk_voucher(), voucherVO);
						}
					}
				}
				if (idset.size() > 0) {
					VoucherVO[] rtvos = (new VoucherBO()).queryRTByPks(idset.toArray(new String[0]));
					for (VoucherVO voucherVO : rtvos) {
						if (voucherVO != null) {
							voMap.put(voucherVO.getPk_voucher(), voucherVO);
						}
					}
				}
				if (voMap.size() > 0) {
					List<VoucherVO> orderVOs = new ArrayList<VoucherVO>();
					for (String id : ids) {
						if (voMap.get(id) != null)
							orderVOs.add(voMap.get(id));
					}
					for (VoucherVO vo : orderVOs) {
						if (userMap != null && userMap.containsKey("printmode") && "1".equals(userMap.get("printmode"))) {

							List selectIndex = (List) userMap.get("selectIndex");
							if (selectIndex == null || selectIndex.size() == 0) {
								throw new RuntimeException(NCLangRes4VoTransl.getNCLangRes().getStrByID("20021005", "UPT2002100573-900048"));
							}
							VoucherVO newvo = (VoucherVO) vo.clone();
							for (int k = 0; k < selectIndex.size(); k++) {
								DetailVO detailVO = vo.getDetail(Integer.valueOf(selectIndex.get(k).toString()).intValue());
								newvo.setDetails(new DetailVO[] { detailVO });
								addVoucher(m_printsubjlevel, m_printasslevel, isParallelPrint, printpagelength, totaltype, dslist, newvo);
							}

							continue;
						}

						if (splitfinf) {
							Map<String, VoucherVO> map = DoubleDetailUtils.splitvoucher(vo);
							VoucherVO finance = map.get(DoubleDetailUtils.TYPE_FINANCE);
							VoucherVO budget = map.get(DoubleDetailUtils.TYPE_BUFGET);
							if (budget != null && budget.getNumDetails() > 0) {
								addVoucher(m_printsubjlevel, m_printasslevel, isParallelPrint, printpagelength, totaltype, dslist, budget);
							}
							if (finance != null && finance.getNumDetails() > 0)
								addVoucher(m_printsubjlevel, m_printasslevel, isParallelPrint, printpagelength, totaltype, dslist, finance);
							continue;
						}
						addVoucher(m_printsubjlevel, m_printasslevel, isParallelPrint, printpagelength, totaltype, dslist, vo);

					}

				}

			}

		} catch (BusinessException e) {
			Logger.error(e.getMessage());
			throw new BusinessRuntimeException(e.getMessage());
		}
		return dslist.toArray(new IDataSource[0]);
	}

	private void addVoucher(int m_printsubjlevel, int m_printasslevel, boolean isParallelPrint, int printpagelength,
			int totaltype, List<IDataSource> dslist, VoucherVO vo) {
		VoucherPrintFormat voucherPrintFormat = new VoucherPrintFormat(vo, m_printsubjlevel, m_printasslevel,
				isParallelPrint);

		voucherPrintFormat.setPrintpagelength(printpagelength);
		voucherPrintFormat.setTotaltype(totaltype);
		Map<String, String[]> voucherMap = voucherPrintFormat.getVoucherPrintItem();
		VoucherPrintDataSource ds = new VoucherPrintDataSource(voucherMap);
		ds.setNumbervo(voucherPrintFormat.getPrintNumberVO());
		dslist.add(ds);
	}

	private Map getVoucherPdf(IPrintInfo info) {
		Map<String, Object> map = new HashMap<String, Object>();
		NoPreviewPrintInfo printInfo = (NoPreviewPrintInfo) info;
		String[] pkDocs = printInfo.getIds();
		printInfo.setIds(new String[] { pkDocs[0].split("\\.")[0].substring(8) });
		IDataSource[] dataSources = getDataSources(info);
		ByteArrayOutputStream out = new ByteArrayOutputStream();

		try {
			NCLocator.getInstance().lookup(IPrintEntry.class).exportPdf(dataSources,
					info.getPrintTemplateID(), out);
		} catch (PrintException e) {
			Logger.error(e.getMessage(), e);
		}
		InputStream ins = new ByteArrayInputStream(out.toByteArray());

		map.put("suffx", pkDocs[0].split("\\.")[pkDocs[0].split("\\.").length - 1]);
		map.put("filestream", ins);
		return map;
	}

	public Map getFileStreams(IPrintInfo info) {
		Map<String, Object> map = new HashMap<String, Object>();
		NoPreviewPrintInfo printInfo = (NoPreviewPrintInfo) info;
		String[] pkDocs = printInfo.getIds();
		if (pkDocs[0].startsWith("VOUCHER")) {
			return getVoucherPdf(printInfo);
		}
		for (int i = 0; i < pkDocs.length; i++) {
			try {
				IAttachmentService ncservice = NCLocator.getInstance()
						.lookup(IAttachmentService.class);
				InputStream in = ncservice.download("z", pkDocs[i].split("\\.")[0], IAttachManageConst.RIAMoudleID);

				ByteArrayOutputStream out = new ByteArrayOutputStream();
				byte[] bytes = new byte[2048];
				int n = -1;

				while ((n = in.read(bytes, 0, bytes.length)) != -1) {
					out.write(bytes, 0, n);
				}
				InputStream ins = new ByteArrayInputStream(out.toByteArray());
				map.put("suffx", pkDocs[i].split("\\.")[pkDocs[i].split("\\.").length - 1]);
				map.put("filestream", ins);
				return map;
			} catch (Exception e) {
				Logger.error(e.getMessage(), e);
			}
		}
		return null;
	}
}
